/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package IA;
import java.util.*;
/**
 *
 * @author Jeremy
 */
public class Server implements KitchenWatcherInterface, ClockObserverInterface {
    private ArrayList<Integer> _tableids;
    private HashMap<Integer, Integer> _RemainingDeliveryTimes;
    private HashMap<Integer, ServerWatcherInterface> _ServerWatchers;
    private final int DEFAULT_DELIVERY_TIME = 5;
    private int _DeliveryTime;
    private int _id;
    
    public Server(int ID, Observable Kitchen) {
        _DeliveryTime = DEFAULT_DELIVERY_TIME;
        _id = ID;
        _RemainingDeliveryTimes = new HashMap<Integer, Integer>();
        _ServerWatchers = new HashMap<Integer, ServerWatcherInterface>();
        _tableids = new ArrayList<Integer>();
        Kitchen.AddObserver(this);
        SystemClock.getInstance().AddObserver(this);
    }
    
    public boolean IsAssignedTo(int TableID) {
        return _tableids.contains(TableID);
    }
    
    public boolean IsDeliveringFor(int TableID) {
        return _RemainingDeliveryTimes.containsKey(TableID);
    }    
    public void setDeliveryTime(int DT) {
        _DeliveryTime = DT;
    }
    
    public int getID() {
        return _id;
    }
    
    public void assignToTable(int TableID, ServerWatcherInterface service) {
        _tableids.add(TableID);
        _ServerWatchers.put(TableID, service);
    }
    
    public void removeFromTable(int TableID) {
        _tableids.remove(_tableids.indexOf(TableID));
    }
    
    public int numTablesAssigned() {
        return _tableids.size();
    }
    
    public static Comparator getShortestWorkloadComparator() {
        return new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                Server s1 = (Server)o1; Server s2 = (Server)o2;
                if(s1.numTablesAssigned() < s2.numTablesAssigned()) return -1;
                else {
                    if(s1.numTablesAssigned() == s2.numTablesAssigned()) return 0;
                    else return 1;
                }
            }
            
        };
    }

    @Override
    public void OrderUp(int TableID) {
       
        if(_tableids.contains(TableID)) {

            _RemainingDeliveryTimes.put(TableID, _DeliveryTime);
        }
    }

    @Override
    public void clockTick() {
        for(Iterator<Map.Entry<Integer,Integer>> itr = _RemainingDeliveryTimes.entrySet().iterator(); itr.hasNext(); ) {
            Map.Entry<Integer,Integer> e = itr.next();
            Integer TableID = e.getKey();
            Integer TimeLeft = e.getValue();
           
            if(--TimeLeft == 0) {
                Deliver(TableID);
                itr.remove();
                _tableids.remove(TableID);
            }
            else _RemainingDeliveryTimes.put(TableID,TimeLeft);
        }
    }

    private void Deliver(int TableID) {
        ServerWatcherInterface service = _ServerWatchers.get(TableID);
        service.OrderDelivered();
    }
}
